package com.cevent.community.app.template.generator;/**
 * Created by Cevent on 2021/9/15.
 */

import com.cevent.community.app.common.domain.Member;
import com.cevent.community.app.common.enums.YesOrNoEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author cevent
 * @description 枚举自动生成器
 * @date 2021/9/15 11:19
 */
public class EnumsApplication {
    private static final Logger LOG= LoggerFactory.getLogger(EnumsApplication.class);
    static String PARENT_DIR="com_cevent_communit_app";
    static String PATH="view_client_template\\public\\common\\js\\enums.js";

    public static void main(String[] args) {
        //构建前端strBuffer(OBJ)集合
        StringBuffer objBuffer=new StringBuffer();
        //构建前端每个obj包含的数组
        StringBuffer objBufferArr=new StringBuffer();
        long begin=System.currentTimeMillis();

        try {
            //传入需要转换的Enum，stringBuffer构造字符串
            enumToJson(YesOrNoEnum.class,objBuffer,objBufferArr);
            //存入buffer
            StringBuffer stringBuffer=objBuffer.append("\r\n").append(objBufferArr);
            //写入js
            writeJS(stringBuffer);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        long end=System.currentTimeMillis();
        LOG.info("enums枚举自动生成前端JS执行耗时：{} 毫秒！",(end-begin));
    }

    //enum转换json方法
    private static void enumToJson(Class clazz,StringBuffer objBuffer,StringBuffer objBufferArr)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        //json--> key配置：类名转换下划线
        String key=toUnderLine(clazz.getSimpleName());
        //将key传入toJson
        enumToJson(clazz,key,objBuffer,objBufferArr);
    }

    private static void enumToJson(Class clazz,String key,StringBuffer objBuffer,StringBuffer objBufferArr)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //通过反射，获取枚举变量数组
        Object[] objs=clazz.getEnumConstants();
        Method name=clazz.getMethod("name");
        Method getDesc=clazz.getMethod("getDesc");
        Method getCode=clazz.getMethod("getCode");
        //生成对象集合,enums.js的key和value
        objBuffer.append(key).append("={");
        for(int i=0;i<objs.length;i++){
            Object obj=objs[i];
            if(getCode==null){
                objBuffer.append(name.invoke(obj))
                        .append(":{key:\"")
                        .append(name.invoke(obj))
                        .append("\",value:\"")
                        .append(getDesc.invoke(obj))
                        .append("\"}");
            }else{
                objBuffer.append(name.invoke(obj))
                        .append(":{key:\"")
                        .append(getCode.invoke(obj))
                        .append("\",value:\"")
                        .append(getDesc.invoke(obj))
                        .append("\"}");
            }
            if(i<objs.length-1){
                objBuffer.append(",");
            }
        }
        objBuffer.append("};\r\n");

        //生成数组，后缀加_ARRAY
        objBufferArr.append(key).append("_ARRAY=[");
        for(int i=0;i<objs.length;i++){
            Object obj=objs[i];
            if(getCode==null){
                objBufferArr.append("{key:\"")
                        .append(name.invoke(obj))
                        .append("\",value:\"")
                        .append(getDesc.invoke(obj))
                        .append("\"}");
            }else{
                objBufferArr.append("{key:\"")
                        .append(getCode.invoke(obj))
                        .append("\",value:\"")
                        .append(getDesc.invoke(obj))
                        .append("\"}");
            }
            if(i<objs.length-1){
                objBufferArr.append(",");
            }
        }
        objBufferArr.append("];\r\n");
    }

    /**
     * 大驼峰：转 大写_下划线，并去掉_ENUM
     * 如：SectionChargeEnum 转为SECTION_CHARGE
     */
    public static String toUnderLine(String clazz){
        String result=underLineName(clazz).toString();
        //将underLineName转化的 _小写属性 转为_大写属性，将enum后缀删除
        return result.substring(1,result.length()).toUpperCase().replaceAll("_ENUM","");
    }
    //大写转_下划线
    public static StringBuffer underLineName(String name){
        //正则匹配match方法,获取大写字母
        Pattern pattern=Pattern.compile("[A-Z]");
        Matcher matcher=pattern.matcher(name);
        //作为缓存
        StringBuffer stringBuffer=new StringBuffer(name);
        //找到匹配正则，执行更新
        if(matcher.find()){
            stringBuffer=new StringBuffer();
            //将大写字母前加_,转为小写字符
            matcher.appendReplacement(stringBuffer,"_"+matcher.group(0).toLowerCase());
            matcher.appendTail(stringBuffer);
        }else{
            return stringBuffer;
        }
        return underLineName(stringBuffer.toString());
    }

    //写入js
    public static void writeJS(StringBuffer stringBuffer){
        FileOutputStream fileOutputStream=null;
        try {
            fileOutputStream=new FileOutputStream(PATH);
            OutputStreamWriter outputStreamWriter=new OutputStreamWriter(fileOutputStream,"UTF-8");
            LOG.info("enums枚举转换应用，映射到的目录：{}",PATH);
            outputStreamWriter.write(stringBuffer.toString());
            outputStreamWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
